<?php
/**
 * 得意基础库(时间通用处理函数)
 *
 * @author liang<lang@vip.deyi.com>
 * @since   2015/6/1 10:03
 * @copyright  deyi.com
 */

namespace Deyi\Functions;

/**
 * Class DateTimeFunction
 * @package Deyi\Functions
 */
class DateTimeFunction
{

    /**
     *  获取相对时间显示格式
     *
     * @author liang<lang@vip.deyi.com>
     * @param $timestamp
     * @return bool|string
     */
    public static function getRelativeDate($timestamp, $type = 0)
    {

        $now = time();
        $diff = $now - $timestamp;
        if ($diff <= 60) {
            return '刚刚';
        }

        if ($diff <= 3600) {
            return (int)($diff / 60) . '分钟前';
        }

        if ($diff <= 86400) {
            return (int)($diff / 3600) . '小时前';
        }

        if ($type == 1) {
            return date('m月d日 H:i', $timestamp);
        }

        return date('Y年m月d日', $timestamp);
    }

    /**
     *  获取执行耗时
     *
     * @author liang<lang@vip.deyi.com>
     * @return float|mixed
     */
    public static function getExecutionTime()
    {
        static $microtime_start = null;
        if ($microtime_start === null) {
            $microtime_start = microtime(true);

            return 0.0;
        }

        return microtime(true) - $microtime_start;
    }

    /**
     *  获取距离明天凌晨整点时间差秒数
     *
     * @author liang<lang@vip.deyi.com>
     * @return int
     */
    public static function getSecondsOffsetNextDay()
    {
        return strtotime(date('Y-m-d', strtotime('+1 day'))) - time();
    }

    /**
     *  判断当前时间是否在指定的时间范围内(starttime和endtime需要在两天跨度比较)
     *
     * @author liang<lang@vip.deyi.com>
     * @param $startTime
     * @param $endTime
     * @return bool
     */
    public static function inTimeRange($startTime, $endTime)
    {
        $curTime = time();

        if ($curTime <= $endTime || $curTime >= $startTime) {
            return true;
        }

        return false;
    }

    /**
     * 判断当前时间是否在指定的时间范围内(starttime和endtime需要在1天跨度比较)
     * @version APP 6.3.5
     * @author lang@vip.deyi.com
     * @param $startTime
     * @param $endTime
     * @return bool
     */
    public static function inTimeRangeInDay($startTime, $endTime)
    {
        $curTime = time();

        if ($curTime <= $endTime && $curTime >= $startTime) {
            return true;
        }

        return false;
    }

    /**
     *  获取上周周一日期
     *
     * @author liang<lang@vip.deyi.com>
     * @return bool|string
     */
    public static function getPrevWeekMonday()
    {
        return date('Y-m-d', strtotime('-' . (date('N') + 6) . 'day'));
    }

    /**
     *  获取上周周日日期
     *
     * @author liang<lang@vip.deyi.com>
     * @return bool|string
     */
    public static function getPrevWeekSunday()
    {
        return date('Y-m-d', strtotime('-' . date('N') . 'day'));
    }

    /**
     *  获取毫秒时间戳(标准时间戳后面再增加3位为毫秒数拼接为13位长度数字，类似于java时间戳)
     *
     * @author liang<lang@vip.deyi.com>
     */
    public static function getCurrentMsecTimestamp()
    {
        return round(microtime(true) * 1000);
    }

    // 夺宝时间计算修复起始时间
    const FIX_BEGIN_DATELINE = 1469064300000;

    /**
     * 毫秒时间戳转换为时间数字字符串（仅针对夺宝时间使用）
     *
     * @author liang<lang@vip.deyi.com>
     * @param $timestamp
     * @deprecated
     * @return int
     */
    public static function msecTimestampToTimeString($timestamp)
    {
        // fix 原先如果毫秒末尾是0的时候被抛弃的问题，但是原有已经转换过的数据只能使用老的计算规则要不然计算的中奖值有误
        if ($timestamp >= self::FIX_BEGIN_DATELINE) {
            $timestamp = strval($timestamp);

            return intval(date('His', substr($timestamp, 0, 10)) . substr($timestamp, -3));
        }

        $tmp = ($timestamp / 1000) . '';
        $tmp = explode('.', $tmp);

        return intval(date('His', $tmp[0]) . $tmp[1]);
    }

    /**
     * 毫秒时间戳转换为正常时间值（仅针对夺宝时间使用）
     *
     * @author liang<lang@vip.deyi.com>
     * @param $timestamp
     * @deprecated
     * @return string
     */
    public static function msecTimestampConvert($timestamp)
    {
        if ($timestamp >= self::FIX_BEGIN_DATELINE) {
            $timestamp = strval($timestamp);

            return date('Y-m-d H:i:s', substr($timestamp, 0, 10)) . '.' . substr($timestamp, -3);
        }

        $tmp = ($timestamp / 1000) . '';
        $tmp = explode('.', $tmp);

        return date('Y-m-d H:i:s', $tmp[0]) . '.' . $tmp[1];
    }

    /**
     *  毫秒时间戳转换为正常时间戳
     *
     * @author liang<lang@vip.deyi.com>
     * @param $timestamp
     * @return float
     */
    public static function msTimestampToSecTimestamp($timestamp)
    {
        return round($timestamp / 1000);
    }


    /**
     * 获取离下一分钟还剩下多少秒
     *
     * @author liang<lang@vip.deyi.com>
     * @return int
     */
    public static function getRemainSecNextMinute()
    {
        $diff = strtotime(date('Y-m-d H:i:00', strtotime('+1 min'))) - time();

        return ($diff > 0) ? $diff : 1;
    }

    /**
     *  获取离下一分钟还剩下多少毫秒数
     *
     * @author liang<lang@vip.deyi.com>
     * @return int
     */
    public static function getRemainMsecNextMinute()
    {
        $b = round(microtime(true) * 1000);
        $a = strtotime(date('Y-m-d H:i:00', strtotime('+1 min'))) * 1000;

        $diff = $a - $b;

        if ($diff > 0) {
            return $diff;
        }

        if ($diff == 0) {
            return 60000;
        }

        return (60000 - $diff);
    }

    /**
     * 获取指定时间戳的下一分钟的具体时间戳
     *
     * @author liang<lang@vip.deyi.com>
     * @param $timestamp
     * @return int
     */
    public static function getNextMinTimestamp($timestamp)
    {
        return strtotime(date("Y-m-d H:i:00", strtotime("+1 min", $timestamp)));
    }

    /**
     * 获取某日期的00:00:00的时间戳
     *
     * @author zhangpeng<zpen@vip.deyi.com>
     * @param $date
     * @return int
     */
    public static function getTimestampAtZeroByDate($date)
    {
        return strtotime($date . " 00:00:00");
    }

    /**
     *  获取本周星期一时间戳
     *
     * @author liang<lang@vip.deyi.com>
     * @return false|int
     */
    public static function getCurWeekMondayTs()
    {
        return strtotime(date('Y-m-d', (time() - ((date('w') == 0 ? 7 : date('w')) - 1) * 24 * 3600)));
    }

    /**
     *  获取本周星期天时间戳
     *
     * @author liang<lang@vip.deyi.com>
     * @return false|int
     */
    public static function getCurWeekSundayTs()
    {
        return strtotime(date('Y-m-d', (time() + (7 - (date('w') == 0 ? 7 : date('w'))) * 24 * 3600)));
    }
}
